package org.wang.generalcode.modules.exam.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.wang.generalcode.modules.exam.parser.ExcelQuestionImportResult;
import org.wang.generalcode.modules.exam.parser.QuestionImportResult;
import org.wang.generalcode.modules.exam.parser.TxtQuestionImportResult;
import org.wang.generalcode.modules.exam.pojo.entity.QuestionInfoEntity;
import org.wang.generalcode.modules.exam.pojo.param.QuestionInfoParams;
import org.wang.generalcode.modules.exam.pojo.vo.QuestionInfoVO;
import org.wang.generalcode.modules.exam.service.QuestionInfoService;
import org.wang.generalcode.support.mybaties.Condition;
import org.wang.generalcode.support.mybaties.Query;
import org.wang.generalcode.support.result.PageResult;
import org.wang.generalcode.support.result.Result;
import org.wang.generalcode.support.trans.core.annotation.Translator;
import org.wang.generalcode.support.utils.Func;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 试题信息表前端控制层
 *
 * @author wz
 * @since 2024-11-22
 */
@Tag(name = "试题信息表接口")
@RestController
@RequestMapping("exam/question_info")
@RequiredArgsConstructor
@Slf4j
public class QuestionInfoController {

    private final QuestionInfoService questioninfoService;

    private static final List<String> excelTypes = List.of("xls","xlsx");

    private static final List<String> textTypes = List.of("txt");

    @Operation(summary = "试题信息表分页列表")
    @GetMapping("/page")
    @Translator
    public PageResult<QuestionInfoVO> getQuestionInfoPage(QuestionInfoParams queryParams, Query query) {
        IPage<QuestionInfoVO> result = questioninfoService.getQuestionInfoPage(Condition.getPage(query), queryParams);
        return PageResult.success(result);
    }

    @Operation(summary = "新增试题信息表")
    @PostMapping("/save")
    public Result saveQuestionInfo(@RequestBody @Valid QuestionInfoEntity formData) {
        boolean result = questioninfoService.save(formData);
        return Result.judge(result);
    }

    @Operation(summary = "获取试题信息表表单数据")
    @GetMapping("/detail")
    public Result<QuestionInfoEntity> getQuestionInfoForm(
            @Parameter(name = "主键", required = true) @RequestParam Long id
    ) {
        QuestionInfoEntity formData = questioninfoService.getById(id);
        return Result.success(formData);
    }

    @Operation(summary = "修改试题信息表")
    @PutMapping(value = "/update")
    public Result updateQuestionInfo(
            @RequestBody QuestionInfoEntity entity
    ) {
        boolean result = questioninfoService.updateById(entity);
        return Result.judge(result);
    }

    @Operation(summary = "删除试题信息表")
    @DeleteMapping("/remove")
    public Result deleteQuestionInfos(
            @Parameter(name = "主键集合", required = true) @RequestParam String ids
    ) {
        boolean result = questioninfoService.removeBatchByIds(Func.toLongList(ids));
        return Result.judge(result);
    }

    @GetMapping("/downloadExcel")
    public void downloadExcel(HttpServletResponse response) throws IOException {
        String fileName = "questionImport.xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));

        String fileClassPath = "/templates" + "/" + "excel" + "/" + fileName;
        InputStream inputStream = getClass().getResourceAsStream(fileClassPath);

        ServletOutputStream outputStream = response.getOutputStream();
        ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(inputStream).build();

        excelWriter.finish();
    }

    @GetMapping("/downloadTxt")
    public void downloadTxt(HttpServletResponse response) throws IOException {
        String fileName = "questionImport.txt";
        response.setContentType("text/plain");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));

        String fileClassPath = "/templates" + "/" + "txt" + "/" + fileName;
        InputStream inputStream = getClass().getResourceAsStream(fileClassPath);

        ServletOutputStream outputStream = response.getOutputStream();

        // 创建缓冲区
        byte[] buffer = new byte[1024];
        int bytesRead;

        // 读取并写入内容
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }

        // 关闭流
        outputStream.flush();
        outputStream.close();
        inputStream.close();
    }


    /**
     * 导入试题
     *
     * @param gradeInfoId
     * @param subjectId
     * @param file
     * @return
     */
    @PostMapping("/importQuestion")
    public Result importQuestion(
            HttpServletResponse response,
            @RequestParam Integer schoolType,
            @RequestParam Integer gradeInfoId,
            @RequestParam Integer subjectId,
            @RequestParam MultipartFile file) {
        String contentType = FileUtil.extName(file.getOriginalFilename());
        if (!excelTypes.contains(contentType) && !textTypes.contains(contentType)) {
            return Result.failed("只能导入excel或者txt类型文件");
        }
        try {
            QuestionImportResult questionImportResult = null;
            if (excelTypes.contains(contentType)) {
                questionImportResult = new ExcelQuestionImportResult(file, response);
            } else {
                questionImportResult = new TxtQuestionImportResult(file);
            }

            questionImportResult.readTemplate();

            if (!questionImportResult.isHasData()) {
                return Result.failed(questionImportResult.getErrorMsg());
            }

            List<QuestionInfoEntity> questionInfoList = questionImportResult.getSuccessImportQuestionList();

            int successCount = 0;
            if (CollectionUtil.isNotEmpty(questionInfoList)) {
                successCount = questioninfoService.importQuestion(schoolType, gradeInfoId,
                        subjectId, questionInfoList);
            }


            int failCount = 0;
            List<QuestionInfoEntity> failQuestionList = questionImportResult.getFailImportQuestionList();

            if (failQuestionList != null) {
                failCount = failQuestionList.size();
            }

            // excel 数据校验失败
            String msg = successCount + "道试题导入成功";
            if (ObjectUtils.isNotEmpty(questionImportResult.getErrorMsg())) {
                if (failCount > 0) {
                    msg += "," + failCount + "道试题导入失败(分别为)" + questionImportResult.getErrorMsg();
                }
                return Result.failed(msg + questionImportResult.getErrorFileUrl());
            }
            return Result.success(msg);
        } catch (Exception e) {
            log.error("数据导入失败", e);
        }
        return Result.failed("数据导入失败");
    }

}
